import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

/**
 * @Author: linzp
 * @Date: 2023/10/30/10:47
 */
public class dem0231030 {
    public static void main(String[] args) throws ExecutionException, InterruptedException, TimeoutException {
        CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println("future1");
            return "future1";
        });

        CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(1000 );
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println("future2");
            return "future2";
        });

        CompletableFuture<String> future3 = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(2000 );
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println("future3");
            return "future3";
        });

        CompletableFuture<Void> allOf = CompletableFuture.allOf(future1, future2, future3);
        //voidResult是由 CompletableFuture<Void>  中的参数决定，这里void所以voidResult没有意义，只为满足函数入参
        //而且 CompletableFuture.allOf只能返回void，因为它代表了一个等待所有任务完成的 CompletableFuture，但它本身并不返回具体的结果
        CompletableFuture<String> finalResult = allOf.thenApply(voidResult -> {
            System.out.println(future1.join());
            return future1.join();
        });
        System.out.println(11);

        //这里get是为了保持最多6秒种的阻塞等待，不然直接在上面thenApply.join就结束了
//        finalResult.get(5, TimeUnit.SECONDS);//阻塞报错
        finalResult.get(6, TimeUnit.SECONDS);
//        finalResult.get(5, TimeUnit.SECONDS);//二次get只是取第一次的缓存，
        //join
        allOf.thenApply(voidResult -> {
            System.out.println(future1.join());
            return voidResult;
        }).join();
        System.out.println(33);

        //get
        CompletableFuture<Void> result4 = allOf.thenApply(voidResult -> {
            System.out.println(future1.join());
            return voidResult;
        });

        System.out.println(44);
//        CompletableFuture.allOf(future1,future2,future3).join();

    }
}
